package org.bank.dao;


import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;


import org.bank.dto.AccountTO;
import org.bank.model.Account;
import org.bank.model.Person;

@Stateless
public class AccountDAOImpl implements AccountDAO {
	
	//Dependency injection provided by this bean being a session bean, will give us the instance for Entity manager.
	@PersistenceContext(unitName="BankJPA")
	public EntityManager em ;

	@Override
	public boolean createAccount(AccountTO accountTO) {
		//Creates a new account and persists it into the DB
		Account account = new Account();
		setAccountData(account, accountTO);
		Account acc = em.find(Account.class, account.getID()); //checking if it already exists in the database with the id number.
		
		if(acc == null){ //if it does not exist, we create a new one in the database.
			em.persist(account);
			accountTO.ID = account.getID();
			return true;
		}
		return false;
	}

	@Override
	public AccountTO findAccount(int accountNumber) {
		// gets an account if it exists from the database.
		Account account =  em.find(Account.class, accountNumber);
		if(account!=null)
			return getAccountData(account); //we just need the TO
		else
			return null;
	}

	@Override
	public boolean setBalance(int accountNumber, double balance) {
		// modifies the balance of an account with the specified account number
		Account account = em.find(Account.class, accountNumber);
		if(account != null)
		{
			account.setBalance(balance);
			em.persist(account);
			return true;
		}
		return false;
	}

	@Override
	public boolean updateAccount(AccountTO accountTO) {
		//here we will update only the private data so as not to touch the balance
		Account account2 = em.find(Account.class, accountTO.ID);
		if(account2 != null)
		{
			Person person = new Person(); //create and populate a Person with its data
			person.setAddress(accountTO.address);
			person.setFirstName(accountTO.firstName);
			person.setLastName(accountTO.lastName);
			person.setPhone(accountTO.phone);
			account2.setPerson(person);
			em.persist(account2); //when we persist the account, the person associated with it is persisted too because they have a relationship together in the DB 
								  //specified by the annotations we have made.
			return true;
		}
		return false; //account did not exist in the first place.
		// TODO Auto-generated method stub
		
	}
	
	//method to get the transfer object for the data of the account
		public AccountTO getAccountData(Account account)
		{
			return createAccountTO(account); //convert from account to accountTO
		}
		
		//method to create a new transfer object with the values of this entity bean
		private AccountTO createAccountTO(Account account) {
			//get the data from the account
			AccountTO accountTO = new AccountTO();
			accountTO.PERSON_ID = account.getPerson().getID();
			accountTO.address = account.getPerson().getAddress();
			accountTO.balance = account.getBalance();
			accountTO.firstName = account.getPerson().getFirstName();
			accountTO.ID = account.getID();
			accountTO.lastName = account.getPerson().getLastName();
			accountTO.phone = account.getPerson().getPhone();
			return accountTO;
			
		}
		
		//method to set this entity values to those of the transfer object
		public void setAccountData(Account account, AccountTO updatedAccount)
		{
			mergeAccountData(account, updatedAccount);
		}
		
		//method to merge the attributes of the TO with those of the bean
		private void mergeAccountData(Account account, AccountTO updatedAccount) {
			//updating the account information and person associated with it from the data in the TO.
			Person person = new Person();
			person.setID(updatedAccount.PERSON_ID);
			person.setAddress(updatedAccount.address);
			account.setBalance(updatedAccount.balance);
			person.setFirstName(updatedAccount.firstName);
			account.setID(updatedAccount.ID);
			person.setLastName(updatedAccount.lastName);
			person.setPhone(updatedAccount.phone);
			account.setPerson(person);
		}

}
